//
//  BezierView.m
//  DebugDemo
//
//  Created by XFB on 2019/5/13.
//  Copyright © 2019 ZhouCheng. All rights reserved.
//

#import "BezierView.h"

@interface BezierView ()
{
    CGRect bezierFrame;
    CGContextRef _context;
}

@end

@implementation BezierView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        bezierFrame = frame;
    }
    return self;
}

/// 画竖线
- (void)drawVerticalLine:(NSArray *)x_names
{
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    NSInteger count = x_names.count;
    CGFloat width = 30;
    CGFloat y = CGRectGetHeight(bezierFrame)-10*20-30;
    CGFloat y1 = CGRectGetHeight(bezierFrame)-30;
    for (NSInteger i = 0; i < count; i ++) {
        [path moveToPoint:CGPointMake(60 + i*width, y)];
        [path addLineToPoint:CGPointMake(60 + i*width, y1)];
    }
    
    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.path = path.CGPath;
    layer.strokeColor = [UIColor lightGrayColor].CGColor;
    layer.lineWidth = 1;
    [self.layer addSublayer:layer];
}

/// 画横线
- (void)drawHorizontalLine:(NSArray *)x_names
{
    CGFloat count = x_names.count;
    CGFloat margin = 20;
    UIBezierPath *path = [UIBezierPath bezierPath];
    CGFloat y = CGRectGetHeight(bezierFrame)-10*20-30;
    for (NSInteger i = 0; i < 10; i ++) {
        [path moveToPoint:CGPointMake(30, y+i*margin)];
        [path addLineToPoint:CGPointMake(30+count*30, y+i*margin)];
    }
    
    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.path = path.CGPath;
    layer.strokeColor = [UIColor lightGrayColor].CGColor;
    layer.lineWidth = 1;
    [self.layer addSublayer:layer];
}

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    _context = context;
}

/**
 画曲线
 
 @param x_names x轴坐标值数组
 @param y_values y轴坐标数组
 @param lineType 直线or曲线
 */
- (void)drawLineViewWithX_Values_Names:(NSMutableArray *)x_names
                              y_values:(NSMutableArray *)y_values
                              lineType:(LineType)lineType
                        gradientColors:(nonnull NSArray *)gradientColors
{
    /// 1、画坐标轴
    [self drawXYLine:x_names];
//    /// 绘制竖线
//    [self drawVerticalLine:x_names];
//    /// 绘制横线
//    [self drawHorizontalLine:x_names];
    
    CGPoint firstPoint ;
    /// 2、获取目标值的坐标
    NSMutableArray *allPoints = @[].mutableCopy;
    for (NSInteger i = 0; i < y_values.count; i ++) {
        // y值放大两倍 因为是20px一格
        CGFloat doubleValue = 2 * [y_values[i] floatValue];
        CGFloat x = 30 + 30*(i + 1);
        CGFloat y = CGRectGetHeight(bezierFrame)-30-doubleValue;
        CGPoint point = CGPointMake(x, y);
        
        if (i == 0) {
            firstPoint = CGPointMake(x, y);
        }
        
        // 画矩形，但是这个矩形是可以画圆角的。第一个参数是矩形，第二个参数是圆角大小。
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(point.x-1.25, point.y-1.25, 2.5, 2.5) cornerRadius:1.25];
        
        CAShapeLayer *layer = [CAShapeLayer layer];
        // 路径颜色
        layer.strokeColor = [UIColor purpleColor].CGColor;
        // 填充内部的颜色，默认黑色。支持动画
        layer.fillColor = [UIColor purpleColor].CGColor;
        // 路径,CASshapeLayer就是根据这个路径绘制图形的
        layer.path = path.CGPath;
        [self.layer addSublayer:layer];
        [allPoints addObject:[NSValue valueWithCGPoint:point]];
    }
    
    /// 3、这是曲线or直线路径
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    // 设置起点
    [bezierPath moveToPoint:[allPoints[0] CGPointValue]];
    
    /// 这是阴影的路径
    UIBezierPath *bezierPath1 = [UIBezierPath bezierPath];
    [bezierPath1 moveToPoint:[allPoints[0] CGPointValue]];
    
    /// 下一个坐标 or 最后点坐标
    CGPoint presentPoint;
    switch (lineType) {
        case LineType_Straight: // 直线
            for (NSInteger i = 0; i < allPoints.count; i ++) {
                CGPoint point = [allPoints[i] CGPointValue];
                [bezierPath addLineToPoint:point];
                /// 阴影路径
                [bezierPath1 addLineToPoint:point];
                presentPoint = [allPoints[i] CGPointValue];
            }
            break;
        case LineType_Curve: // 曲线
            for (NSInteger i = 0; i < allPoints.count; i ++) {
                if (i == 0) {
                    presentPoint = [allPoints[i] CGPointValue];
                } else {
                    CGPoint nowPoint = [allPoints[i] CGPointValue];
                    // 三次贝塞尔曲线的关键方法
                    // 以三个点画一段曲线，一般和moveToPoint:配合使用
                    // 其实端点为moveToPoint：设置终端点为endPoint
                    [bezierPath addCurveToPoint:nowPoint
                                  controlPoint1:CGPointMake((presentPoint.x+nowPoint.x)/2, presentPoint.y)
                                  controlPoint2:CGPointMake((presentPoint.x+nowPoint.x)/2, nowPoint.y)];
                    /// 阴影路径
                    [bezierPath1 addCurveToPoint:nowPoint
                                   controlPoint1:CGPointMake((presentPoint.x+nowPoint.x)/2, presentPoint.y)
                                   controlPoint2:CGPointMake((presentPoint.x+nowPoint.x)/2, nowPoint.y)];
                    presentPoint = nowPoint;
                }
            }
            break;
        default:
            break;
    }
    
    /// 获取最后一个点X轴坐标
    CGFloat lastPointX = presentPoint.x;
    /// 最后点 到 最后点的Y轴坐标为0
    [bezierPath1 addLineToPoint:CGPointMake(lastPointX, CGRectGetHeight(bezierFrame))];
    /// 最后点的Y轴坐标为0 到 起点的Y轴坐标为0
    [bezierPath1 addLineToPoint:CGPointMake(firstPoint.x, CGRectGetHeight(bezierFrame))];
    /// 起点的Y轴坐标为0 到 起点 (回到原点)
    [bezierPath1 addLineToPoint:CGPointMake(firstPoint.x, firstPoint.y)];
    
    /// 阴影的layer
    CAShapeLayer *shadeLayer = [CAShapeLayer layer];
    shadeLayer.path = bezierPath1.CGPath;
    // 渐变图层
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = CGRectMake(30, 0, 0, CGRectGetHeight(bezierFrame)-30);
    gradientLayer.startPoint = CGPointMake(0, 0);
    gradientLayer.endPoint = CGPointMake(0, 1);
    gradientLayer.cornerRadius = 5;
    gradientLayer.masksToBounds = YES;
    
    CGColorRef startColor = RGBA(239, 152, 0, 0.8).CGColor;
    CGColorRef endColor = RGBA(239, 152, 0, 0.2).CGColor;
//    CGColorRef endColor = UIColorFromRGB(0xFFFFFF).CGColor;
    gradientLayer.colors = gradientColors;
//                            @[(__bridge id)startColor,
//                             (__bridge id)endColor];
    gradientLayer.locations = @[@(0.5)];
    
    CALayer *baseLayer = [CALayer layer];
    [baseLayer addSublayer:gradientLayer];
    [baseLayer setMask:shadeLayer];
    [self.layer addSublayer:baseLayer];
    
    CABasicAnimation *anmation1 = [CABasicAnimation animation];
    anmation1.keyPath = @"bounds";
    anmation1.duration = 2.0f;
    // 保存CGRect结构体 
    anmation1.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, presentPoint.x*2, CGRectGetHeight(bezierFrame)-30)];
    // 速度控制函数，控制动画运行的节奏
    anmation1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
    // 当动画结束后，layer会一直保持着动画最后的状态
    anmation1.fillMode = kCAFillModeForwards;
    // 设置这个属性表示完成动画后会回到执行动画之前的状态
    anmation1.autoreverses = NO;
    // 默认为YES，代表动画执行完毕后就从图层上移除，图形会恢复到动画执行前的状态。
    // 如果想让图层保持显示动画执行后的状态，那就设置为NO，不过还要设置fillMode为kCAFillModeForwards
    anmation1.removedOnCompletion = NO;
    [gradientLayer addAnimation:anmation1 forKey:@"bounds"];

    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = bezierPath.CGPath;
    // 路径颜色
    shapeLayer.strokeColor = [UIColor redColor].CGColor;
    // 填充颜色
    shapeLayer.fillColor = [UIColor clearColor].CGColor;
    shapeLayer.borderWidth = 2.0;
    [self.layer addSublayer:shapeLayer];
    
    /// 添加路径动画连线
    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnimation.duration            = 2;
    pathAnimation.repeatCount         = 1;
    pathAnimation.removedOnCompletion = YES;
    pathAnimation.fromValue           = @0;
    pathAnimation.toValue             = @1;
    pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [shapeLayer addAnimation:pathAnimation forKey:@"strokeEnd"];

    /// 4、添加目标值文字
    for (NSInteger i = 0; i < allPoints.count; i ++) {
        UILabel *label = [[UILabel alloc] init];
        label.textColor = [UIColor purpleColor];
        label.textAlignment = NSTextAlignmentCenter;
        label.font = [UIFont systemFontOfSize:10];
        [self addSubview:label];
        
        if (i == 0) {
            CGPoint nowPoint = [allPoints[0] CGPointValue];
            label.text = [NSString stringWithFormat:@"%.01f", (CGRectGetHeight(bezierFrame)-nowPoint.y-30)/2];
            label.frame = CGRectMake(nowPoint.x-30/2, nowPoint.y-20, 30, 20);
            presentPoint = nowPoint;
        } else {
            CGPoint nowPoint = [allPoints[i] CGPointValue];
            label.frame = CGRectMake(nowPoint.x-30/2, nowPoint.y-20, 30, 20);
//            if (nowPoint.y < presentPoint.y) {
//                // 文字置于点上方
//                label.frame = CGRectMake(nowPoint.x-30/2, nowPoint.y-20, 30, 20);
//            } else {
//                // 文字置于点下方
//                label.frame = CGRectMake(nowPoint.x-30/2, nowPoint.y, 30, 20);
//            }
            label.text = [NSString stringWithFormat:@"%.01f", (CGRectGetHeight(bezierFrame)-nowPoint.y-30)/2];
            presentPoint = nowPoint;
        }
    }
    
    UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, [UIScreen mainScreen].scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 1);
    
    /// 一般不行 UIGraphicsGetCurrentContext 放在drawRect方法里面
//    CGContextRef context = UIGraphicsGetCurrentContext();
    _context = context;
    for (NSInteger i = 0; i < x_names.count; i ++) {
        CGPoint endPoint = [allPoints[i] CGPointValue];
        UIColor *lineColor = [UIColor blackColor];
        // 绘制虚线
        CGPoint startPoint = CGPointMake(30, endPoint.y);
        // 移动到点
        CGContextMoveToPoint(_context, startPoint.x, startPoint.y);
        NSLog(@"%@----%@", NSStringFromCGPoint(startPoint), NSStringFromCGPoint(endPoint));
        // 连接到
        CGContextAddLineToPoint(_context, endPoint.x, endPoint.y);
        CGContextSetLineWidth(_context, 0.5);
        [lineColor setStroke];
        CGFloat locations[] = {0.5, 2};
        CGContextSetLineDash(_context, 0, locations, 2);
        CGContextDrawPath(_context, kCGPathFillStroke);
    }
}

/**
 矩形图
 
 @param x_names x轴坐标值数组
 @param y_values y轴坐标值数组
 */
- (void)drawBarChartViewWithX_Values_Names:(NSMutableArray *)x_names
                                  y_values:(NSMutableArray *)y_values
{
    /// 1、画XY坐标轴
    [self drawXYLine:x_names];
    
    /// 2、每一个目标值点坐标
    for (NSInteger i = 0; i < y_values.count; i ++) {
        CGFloat doubleValue = 2 * [y_values[i] floatValue];
        CGFloat x = 30 + 30 * (i + 1) + 5;
        CGFloat y = CGRectGetHeight(bezierFrame)-30-doubleValue;
        
        UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(x-30/2, y, 30-10, doubleValue)];        
        CAShapeLayer *shapeLayer = [CAShapeLayer layer];
        shapeLayer.path = bezierPath.CGPath;
        shapeLayer.strokeColor = [UIColor clearColor].CGColor;
        shapeLayer.fillColor = RandomColor.CGColor;
        
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(x-30/2, y-20, 30-10, 20)];
        label.text = [NSString stringWithFormat:@"%.0lf",(CGRectGetHeight(bezierFrame)-y-30)/2];
        label.textColor = [UIColor purpleColor];
        label.textAlignment = NSTextAlignmentCenter;
        label.font = [UIFont systemFontOfSize:10];
        [self addSubview:label];

        [self.layer addSublayer:shapeLayer];
    }
}


/**
 饼状图
 
 @param x_names x轴坐标值数组
 @param y_values y轴坐标值数组
 */
- (void)drawPieChartViewWithX_Values_Names:(NSMutableArray *)x_names
                                  y_values:(NSMutableArray *)y_values
{
    /// 1、设置圆点
    CGPoint point = CGPointMake(self.width/2, self.height/2);
    CGFloat startAngle = 0;
    CGFloat endAngle ;
    CGFloat radius = 100;
    
    /// 计算总数
    __block CGFloat allValue = 0;
    [y_values enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        obj = (NSNumber *)obj;
        allValue += [obj floatValue];
    }];
    
    /// 画图
    for (NSInteger i = 0; i < y_values.count; i ++) {
        
        CGFloat targetValue = [y_values[i] floatValue];
        endAngle = startAngle + targetValue/allValue*2*M_PI;
        /// BezierPath 行程闭合的扇形路径
        UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:point radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
        [bezierPath addLineToPoint:point];
        [bezierPath closePath];
        
        /// 添加文字  The Most Important!!!!!!!!!!!!!!
        CGFloat x = point.x + 120*cos(startAngle+(endAngle-startAngle)/2) - 10;
        CGFloat y = point.y + 110*sin(startAngle+(endAngle-startAngle)/2) - 10;
        
        UILabel *label = [[UILabel alloc] init];
        label.frame = CGRectMake(x, y, 30, 20);
        label.text = x_names[i];
        label.font = [UIFont systemFontOfSize:10];
        label.textColor = [UIColor orangeColor];
        [self addSubview:label];
        
        /// 渲染
        CAShapeLayer *shaperLayer = [CAShapeLayer layer];
        shaperLayer.lineWidth = 1;
        shaperLayer.fillColor = RandomColor.CGColor;
        shaperLayer.path = bezierPath.CGPath;
        [self.layer addSublayer:shaperLayer];
        
        startAngle = endAngle;
    }
}


- (void)drawXYLine:(NSMutableArray *)x_names
{
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    /// Y轴的直线
    // 设置第一个起始点到接收器
    [path moveToPoint:CGPointMake(30, CGRectGetHeight(bezierFrame)-30)];
    // 附加一条直线到接收器的路径
    [path addLineToPoint:CGPointMake(30, 30)];
    
    /// X轴直线
    [path moveToPoint:CGPointMake(30, CGRectGetHeight(bezierFrame)-30)];
    [path addLineToPoint:CGPointMake(30 + CGRectGetWidth(bezierFrame)-15, CGRectGetHeight(bezierFrame)-30)];
    
    /// 给Y轴添加箭头
    // Y轴箭头左侧
    [path moveToPoint:CGPointMake(30, 30)];
    [path addLineToPoint:CGPointMake(30-5, 30+5)];
    // Y轴箭头右侧
    [path moveToPoint:CGPointMake(30, 30)];
    [path addLineToPoint:CGPointMake(30+5, 30+5)];
    
    /// 给X轴添加箭头
    // X轴上侧箭头
    [path moveToPoint:CGPointMake(30+CGRectGetWidth(bezierFrame)-15, CGRectGetHeight(bezierFrame)-30)];
    [path addLineToPoint:CGPointMake(30+CGRectGetWidth(bezierFrame)-5-15, CGRectGetHeight(bezierFrame)-30-5)];
    /// X轴下侧箭头
    [path moveToPoint:CGPointMake(30+CGRectGetWidth(bezierFrame)-15, CGRectGetHeight(bezierFrame)-30)];
    [path addLineToPoint:CGPointMake(30+CGRectGetWidth(bezierFrame)-5-15, CGRectGetHeight(bezierFrame)-30+5)];
    
    /// 添加索引格
    /// X轴
    for (NSInteger i = 0; i < x_names.count; i ++) {
        CGFloat x = 30+30*(i + 1);
        CGPoint point = CGPointMake(x, CGRectGetHeight(bezierFrame)-30);
        [path moveToPoint:point];
        [path addLineToPoint:CGPointMake(point.x, point.y-3)];
    }
    
    /// Y轴
    for (NSInteger i = 0; i < 11; i ++) {
        CGFloat y = CGRectGetHeight(bezierFrame)-20*i-30;
        CGPoint point = CGPointMake(30, y);
        [path moveToPoint:point];
        [path addLineToPoint:CGPointMake(point.x+3, point.y)];
    }
    
    /// 添加索引格文字
    // X轴
    for (NSInteger i = 0; i < x_names.count; i ++) {
        CGFloat x = 30 + 15 + 30*i;
        UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(x, CGRectGetHeight(bezierFrame)-30, 30, 20)];
        textLabel.text = x_names[i];
        textLabel.font = [UIFont systemFontOfSize:10];
        textLabel.textAlignment = NSTextAlignmentCenter;
        textLabel.textColor = [UIColor blueColor];
        [self addSubview:textLabel];
    }
    
    // Y轴
    for (NSInteger i = 0; i < 11; i ++) {
        CGFloat y = CGRectGetHeight(bezierFrame)-20*i-30;
        UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, y-5, 30, 10)];
        textLabel.text = [NSString stringWithFormat:@"%ld",10*i];
        textLabel.font = [UIFont systemFontOfSize:10];
        textLabel.textAlignment = NSTextAlignmentCenter;
        textLabel.textColor = [UIColor redColor];
        [self addSubview:textLabel];
    }
    
    /// 渲染路径
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = path.CGPath;
    shapeLayer.strokeColor = [UIColor blackColor].CGColor;
    shapeLayer.fillColor = [UIColor clearColor].CGColor;
    shapeLayer.borderWidth = 2.0;
    [self.layer addSublayer:shapeLayer];
}


@end
